PyTorch TensorBoard 使用
TensorBoard 是什么?
TensorBoard 是 TensorFlow 提供的一个可视化工具,主要用于可视化神经网络的训练过程、结构和其它各种指标。不过,TensorBoard 不仅限于 TensorFlow,它与 PyTorch 也有很好的集成。
为了将数字列表转换为 Markdown 子标题,我们可以使用 ###
。这是怎么做的:
使用 TensorBoard 与 PyTorch,你可以:
- 可视化模型结构。
- 跟踪和可视化模型的训练指标,如损失和准确率。
- 查看梯度的分布和趋势。
- 查看权重、偏置和其他张量的分布和变化。
- 生成图片、音频和文本的可视化。
要在 PyTorch 中使用 TensorBoard,以下是基本步骤:
安装
pip install tensorboard
导入必要的库
from torch.utils.tensorboard import SummaryWriter
创建 SummaryWriter
这个对象是你与 TensorBoard 交互的主要方式。
writer = SummaryWriter('runs/experiment_name')
记录信息
使用 writer
对象来记录想要可视化的信息。
for epoch in range(num_epochs):
# ... training loop ...
writer.add_scalar('Loss/train', loss, epoch)
writer.add_scalar('Accuracy/train', accuracy, epoch)
启动 TensorBoard
在命令行或终端中运行:
tensorboard --logdir=runs
之后,你可以在浏览器中打开 http://localhost:6006/
来查看 TensorBoard 的界面。
每次启动记录新的实验
tensorboard 会在一个目录下持续记录,如果想要记录新的实验,如果不重新创建目录去记录,就会出现下面这样奇怪的图
解决办法就是使用时间戳随机生成一个目录名称
from datetime import datetime
now = datetime.now()
logdir = "runs/" + now.strftime("%Y%m%d-%H%M%S") + ""
writer = SummaryWriter(logdir)
TensorBoard 记录模型的结构
要使用 TensorBoard 记录模型的结构,可以使用 TensorBoard 的 add_graph
方法。这个方法可以捕获模型的计算图并在 TensorBoard 中显示它。以下是如何做到这一点的步骤:
创建 SummaryWriter 对象
writer = SummaryWriter('runs/experiment_name')
记录模型的计算图
为了记录模型的结构,你需要模型的一个实例和一个代表输入的张量。
import torch
import torchvision.models as models
# 获取一个预训练的 resnet18 模型
model = models.resnet18(pretrained=True)
# 创建一个随机输入张量,假设批量大小为 1,通道数为 3,高度和宽度都为 224
input_tensor = torch.rand(1, 3, 224, 224)
# 使用 add_graph 方法记录模型的结构
writer.add_graph(model, input_tensor)
add_graph
函数的主要用途是在 TensorBoard 中可视化模型的计算图。为了实现这一点,该函数需要两个主要输入:模型本身和一个输入张量(即模型的输入数据)。
输入张量的作用有两点:
形状推断:通过将输入张量传递给模型,TensorBoard 可以捕获模型的整个计算图,包括每一层的输入和输出的形状。这有助于为 TensorBoard 用户呈现每一层的维度和大小。
正向传播:输入张量确实会通过模型进行一次前向传播,但实际上不会进行训练(即不会进行反向传播)。这次前向传播的目的是捕获模型的完整计算图。
例如,对于一个典型的卷积神经网络,可能想知道在每一层卷积、池化或全连接层之后,特征图的形状是什么。提供输入张量可以帮助捕获这些信息,并在 TensorBoard 中可视化模型的层次结构和每一层的输出形状。
在实际的训练中,这里可以选取数据集的一部分作为输入张量,然后将其传递给模型。如下代码所示
# 训练模型
num_epochs = 5 # 这只是一个示例值,您可以根据需要进行调整
for epoch in range(num_epochs):
total_loss = 0.0
for i, (inputs, labels) in enumerate(trainloader):
inputs, labels = inputs.to(device), labels.to(device)
# 清零梯度
optimizer.zero_grad()
# 前向传播
outputs = model(inputs)
loss = criterion(outputs.view(-1, len(nums)), labels.view(-1))
loss.backward()
optimizer.step()
total_loss += loss.item()
# 每100批次,记录损失到TensorBoard
if (i + 1) % 100 == 0:
writer.add_scalar('Training Loss', total_loss / (i + 1), epoch * len(trainloader) + i)
print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss / (i + 1):.4f}")
# 在 TensorBoard 中记录模型的结构
inputs, _ = next(iter(trainloader))
inputs = inputs.to(device)
writer.add_graph(model, inputs)
# 关闭 SummaryWriter
writer.close()